import { QuickQueryC, XYAxisChartsC, TableC, ModalC } from '@/src/components';
import styles from './index.less';
import { ExportOutlined, TableOutlined, BarChartOutlined } from '@ant-design/icons';
import React, { useState, useRef, useEffect, forwardRef, useImperativeHandle } from 'react';
import { Row, Col, Tooltip, Space, Spin } from 'antd';
import { connect } from 'umi';
import PropTypes from 'prop-types';
import { exportFile } from 'table-xlsx';
import { saveAs } from 'file-saver';
import { cloneDeep } from 'lodash';
import ResizeObserver from 'resize-observer-polyfill';
import { domElementToImageUrl } from '@/src/utils/utils';
import { reservedBits } from '@/src/utils/commonFunc';

let myObserver = null;
const tableIdForSpreads = 'tableIdForSpreads';
function transChartsData(arr, keys) {
  return arr.map((v) => v[keys]);
}

const DimensionCustomization = forwardRef((props, ref) => {
  const [tab1Column, setTab1Column] = useState([
    { title: '省级', key: 'province', width: 100 },
    {
      title: '信用利差(bp)',
      key: 'creditSpreads',
      sorter: true,
      width: 130,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
    {
      title: '信用利差分位数(%)',
      key: 'creditInterestDiff',
      sorter: true,
      width: 170,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
  ]);
  const [tab2Column, setTab2Column] = useState([
    {
      title: '省级',
      key: 'province',
      width: 100,
    },
    {
      title: '信用利差(bp)',
      key: 'creditSpreads',
      sorter: true,
      width: 130,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
    {
      title: '近三月变动(bp)',
      key: 'pastThreeMonths',
      sorter: true,
      width: 140,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
    {
      title: '近六月变动(bp)',
      key: 'pastSixMonths',
      sorter: true,
      width: 140,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
    {
      title: '近一年变动(bp)',
      key: 'pastOneYear',
      sorter: true,
      width: 140,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
  ]);
  const [tab1ColumnWithCity, setTab1ColumnWithCity] = useState([
    { title: '省级', key: 'province', width: 100 },
    { title: '市级', key: 'city', width: 80 },
    {
      title: '信用利差(bp)',
      key: 'creditSpreads',
      sorter: true,
      width: 130,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
    {
      title: '信用利差分位数(%)',
      key: 'creditInterestDiff',
      sorter: true,
      width: 170,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
  ]);
  const [tab2ColumnWithCity, setTab2ColumnWithCity] = useState([
    { title: '省级', key: 'province', width: 100 },
    { title: '市级', key: 'city', width: 80 },
    {
      title: '信用利差(bp)',
      key: 'creditSpreads',
      sorter: true,
      width: 130,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
    {
      title: '近三月变动(bp)',
      key: 'pastThreeMonths',
      sorter: true,
      width: 140,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
    {
      title: '近六月变动(bp)',
      key: 'pastSixMonths',
      sorter: true,
      width: 140,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
    {
      title: '近一年变动(bp)',
      key: 'pastOneYear',
      sorter: true,
      width: 140,
      align: 'right',
      render: (text) => (text || text === 0 ? reservedBits(text) : '--'),
    },
  ]);
  const { dataSource, onClickRow = () => {}, loading, onTabChange } = props;
  const refCharts2 = useRef();
  const refCharts1 = useRef();
  const refInstance = useRef();
  const [openModal, setOpenModal] = useState(false);
  const [openPopover, setOpenPopover] = useState(false);
  const [tab1, setTab1] = useState('1'); // 信用利差 | 利差变动
  const [tab2, setTab2] = useState('1'); // 省级利差 | 市级利差
  const [series1, setSeries1] = useState([]); // 信用利差 - 表数据
  const [xAxis1, setXAxis1] = useState([]); // 信用利差 - x轴
  const [series2, setSeries2] = useState([]); // 利差变动 - 表数据
  const [xAxis2, setXAxis2] = useState([]); // 利差变动 - x轴
  const [data, setData] = useState([]); // table 数据
  const [dataRaw, setDataRaw] = useState([]); // 原始table 数据
  const [defaultSelectSpreads, setDefaultSelectSpreads] = useState(); // 默认选中的行
  const [chartsHeight, setChartsHeight] = useState(403); // charts的高
  const initData = (dataParams) => {
    // 信用利差
    if (tab1 === '1') {
      const xAxis1Data = transChartsData(dataParams, tab2 === '1' ? 'province' : 'city');
      const series1Data = [
        {
          name: '信用利差（bp）',
          type: 'bar',
          data: transChartsData(dataParams, 'creditSpreads'),
        },
        {
          name: '信用利差分位数（%）',
          type: 'line',
          data: transChartsData(dataParams, 'creditInterestDiff'),
          yAxisIndex: 1,
        },
      ];
      setSeries1(series1Data);
      setXAxis1(xAxis1Data);
      if (!refInstance.current) {
        setDefaultSelectSpreads(dataParams.length > 0 ? dataParams[0][tab2 === '1' ? 'province' : 'city'] : undefined);
      }
    }
    // 利差变动
    if (tab1 === '2') {
      const xAxis2Data = transChartsData(dataParams, tab2 === '1' ? 'province' : 'city');
      const series2Data = [
        {
          name: '近三月',
          data: transChartsData(dataParams, 'pastThreeMonths'),
        },
        {
          name: '近六月',
          data: transChartsData(dataParams, 'pastSixMonths'),
          // yAxisIndex: 1,
        },
        {
          name: '近一年',
          data: transChartsData(dataParams, 'pastOneYear'),
        },
      ];
      setXAxis2(xAxis2Data);
      setSeries2(series2Data);
      if (!refInstance.current) {
        setDefaultSelectSpreads(dataParams.length > 0 ? dataParams[0][tab2 === '1' ? 'province' : 'city'] : undefined);
      }
    }
  };
  useEffect(() => {
    setData(dataSource);
    setDataRaw(dataSource);
  }, [dataSource]);
  useEffect(() => {
    initData(data); // 列表排序后改变图表
  }, [data]);
  const downloadPng = async () => {
    const src = await domElementToImageUrl(document.getElementById('chartsDom'), { scale: 1 });
    saveAs(src, tab1 === '1' ? '信用利差.png' : '利差变动.png');
  };
  const handleExportFile = (et) => {
    setOpenPopover(false);
    if (et === '1') setOpenModal(true); // 图片
    // excel文档
    if (et === '2') {
      exportFile({
        fileName: tab1 === '1' ? '信用利差.xlsx' : '利差变动.xlsx', // 文件名
        columns: tab1 === '1' ? (tab2 === '1' ? tab1Column : tab1ColumnWithCity) : tab2 === '1' ? tab2Column : tab2ColumnWithCity, // 表格columns
        dataSource: data, // 表格dataSource
        raw: true,
        headerCellStyle: {
          fillFgColorRgb: 'e8efff', // header行的填充颜色
        },
      });
    }
  };
  const handleTableChange = (pagination, filters, sorter) => {
    refInstance.current = true;
    const { order, field } = sorter;
    let dataCopy = cloneDeep(data);
    const withNull = dataCopy.filter((v) => v[field] === null);
    const withOutNull = dataCopy.filter((v) => v[field] !== null);
    let resData = [];
    if (order === 'descend') {
      dataCopy.sort((a, b) => b[field] - a[field]);
      resData = [...cloneDeep(withOutNull).sort((a, b) => b[field] - a[field]), ...withNull];
    } else if (order === 'ascend') {
      dataCopy.sort((a, b) => a[field] - b[field]);
      resData = [...cloneDeep(withOutNull).sort((a, b) => a[field] - b[field]), ...withNull];
    } else {
      dataCopy = dataRaw;
      resData = dataRaw;
    }
    setData(resData);
    // 信用利差
    if (tab1 === '1') {
      if (tab2 === '1') {
        const tab1ColumnCopy = cloneDeep(tab1Column);
        tab1ColumnCopy.map((item) => {
          if (item.key === field) {
            item.sortOrder = order;
          } else {
            item.sortOrder = undefined;
          }
        });
        setTab1Column(tab1ColumnCopy);
      }
      if (tab2 === '2') {
        const tab1ColumnWithCityCopy = cloneDeep(tab1ColumnWithCity);
        tab1ColumnWithCityCopy.map((item) => {
          if (item.key === field) {
            item.sortOrder = order;
          } else {
            item.sortOrder = undefined;
          }
        });
        setTab1ColumnWithCity(tab1ColumnWithCityCopy);
      }
    }
    // 利差变动
    if (tab1 === '2') {
      if (tab2 === '1') {
        const tab2ColumnCopy = cloneDeep(tab2Column);
        tab2ColumnCopy.map((item) => {
          if (item.key === field) {
            item.sortOrder = order;
          } else {
            item.sortOrder = undefined;
          }
        });
        setTab2Column(tab2ColumnCopy);
      }
      if (tab2 === '2') {
        const tab2ColumnWithCityCopy = cloneDeep(tab2ColumnWithCity);
        tab2ColumnWithCityCopy.map((item) => {
          if (item.key === field) {
            item.sortOrder = order;
          } else {
            item.sortOrder = undefined;
          }
        });
        setTab2ColumnWithCity(tab2ColumnWithCityCopy);
      }
    }
  };
  const windowChange = () => {
    const tableContent = document.querySelector('#tableIdForSpreads');
    if (tableContent?.clientHeight >= 403) setChartsHeight(tableContent?.clientHeight);
  };
  useEffect(() => {
    // 监听窗口变化
    window.addEventListener('resize', windowChange);
    myObserver = new ResizeObserver((entries) => {
      entries.forEach(() => {
        windowChange();
      });
    });
    myObserver.observe(document.getElementById(tableIdForSpreads));
    return () => {
      myObserver = null;
    };
  }, []);
  const resetRefIns = () => {
    refInstance.current = undefined;
    const tab1ColumnCopy = cloneDeep(tab1Column);
    const tab1ColumnWithCityCopy = cloneDeep(tab1ColumnWithCity);
    const tab2ColumnCopy = cloneDeep(tab2Column);
    const tab2ColumnWithCityCopy = cloneDeep(tab2ColumnWithCity);
    tab1ColumnCopy.map((ele) => {
      if (ele.sorter) ele.sortOrder = undefined;
    });
    setTab1Column(tab1ColumnCopy);
    tab1ColumnWithCityCopy.map((ele) => {
      if (ele.sorter) ele.sortOrder = undefined;
    });
    setTab1ColumnWithCity(tab1ColumnWithCityCopy);
    tab2ColumnCopy.map((ele) => {
      if (ele.sorter) ele.sortOrder = undefined;
    });
    setTab2Column(tab2ColumnCopy);
    tab2ColumnWithCityCopy.map((ele) => {
      if (ele.sorter) ele.sortOrder = undefined;
    });
    setTab2ColumnWithCity(tab2ColumnWithCityCopy);
    setData([]);
  };
  useImperativeHandle(ref, () => ({
    resetRefIns,
  }));
  return (
    <div className={styles.customization}>
      <div className={styles.docker}>
        <div className={styles.tabs}>
          <QuickQueryC
            isInitOnchange={false}
            dataSource={[
              { value: '1', title: '信用利差' },
              { value: '2', title: '利差变动' },
            ]}
            initialValue={tab1}
            onChange={(e) => {
              refInstance.current = undefined;
              setTab1(e);
              onTabChange(e, 'tabLeft');
              setDefaultSelectSpreads(undefined); // 切换tab清空选中项目， 不然排序会破坏当前选中状态，导致重新进入初始化函数的默认选中第一个，
              setData([]); // 切换tab清空data
            }}
          />
          <QuickQueryC
            isInitOnchange={false}
            dataSource={[
              { value: '1', title: '省级利差' },
              { value: '2', title: '市级利差' },
            ]}
            initialValue={tab2}
            onChange={(e) => {
              refInstance.current = undefined;
              setTab2(e);
              onTabChange(e, 'tabRight');
              setDefaultSelectSpreads(undefined); // 切换tab清空选中项目， 不然排序会破坏当前选中状态，导致重新进入初始化函数的默认选中第一个，
              setData([]); // 切换tab清空data
            }}
          />
        </div>
        <Tooltip
          open={openPopover}
          placement='topRight'
          onOpenChange={(open) => setOpenPopover(open)}
          title={
            <Space size={'middle'}>
              <BarChartOutlined style={{ fontSize: 28, cursor: 'pointer' }} onClick={() => handleExportFile('1')} />
              <TableOutlined style={{ fontSize: 28, cursor: 'pointer' }} onClick={() => handleExportFile('2')} />
            </Space>
          }
          trigger='click'
        >
          <span style={{ cursor: 'pointer', fontSize: 34 }}>
            <ExportOutlined style={{ color: '#4376ff' }} />
          </span>
        </Tooltip>
      </div>
      <div className={styles.content}>
        <Row gutter={16}>
          <Col span={document.documentElement?.clientWidth > 1920 ? 18 : 16}>
            <Spin spinning={loading.effects[`creditSpreadAnalysisM/querySpreadAnalysis`]}>
              {tab1 === '2' ? (
                <XYAxisChartsC
                  isResponsiveHeight={true}
                  dataZoom={true}
                  series={series2}
                  xAxis={xAxis2}
                  height={chartsHeight}
                  type='bar'
                  isAbbreviate={true}
                  yAxisUnit={['信用利差(bp)']}
                  toolTipDataFormat={[(value) => `${value}bp`, (value) => `${value}bp`, (value) => `${value}bp`]}
                />
              ) : (
                <div>
                  <XYAxisChartsC
                    isAbbreviate={true}
                    isResponsiveHeight={true}
                    dataZoom={true}
                    yAxisUnit={['信用利差(bp)', '信用利差分位数(%)']}
                    series={series1}
                    xAxis={xAxis1}
                    height={chartsHeight}
                    type='bar'
                  />
                </div>
              )}
            </Spin>
          </Col>
          <Col span={document.documentElement?.clientWidth > 1920 ? 6 : 8}>
            <div id={tableIdForSpreads}>
              <TableC
                rowClassName={(record) => ((tab2 === '1' ? record.province : record.city) === defaultSelectSpreads ? 'defaultSelectSpreads' : '')}
                onRow={(record) => ({
                  onClick: () => {
                    setDefaultSelectSpreads(tab2 === '1' ? record.province : record.city);
                    onClickRow(record);
                  },
                })}
                loading={loading.effects[`creditSpreadAnalysisM/querySpreadAnalysis`]}
                columns={tab1 === '1' ? (tab2 === '1' ? tab1Column : tab1ColumnWithCity) : tab2 === '1' ? tab2Column : tab2ColumnWithCity}
                dataSource={data}
                hidePage={true}
                rowKey={tab2 === '1' ? 'province' : 'city'}
                scroll={{ x: 'max-content', y: 360 }}
                onChange={handleTableChange}
              />
            </div>
          </Col>
        </Row>
      </div>
      <ModalC
        title={'导出'}
        visible={openModal}
        maskClosable={false}
        onOk={downloadPng}
        onCancel={() => setOpenModal(false)}
        width={document.querySelector('#root').offsetWidth}
        height={document.querySelector('#root').offsetHeight}
      >
        <div id={'chartsDom'}>
          {tab1 === '2' ? (
            <XYAxisChartsC
              ref={(ref) => (refCharts2.current = ref)}
              series={series2}
              xAxis={xAxis2}
              height={document.querySelector('#root').offsetHeight - 170}
              type='bar'
              isAbbreviate={true}
              axisLabelFormatter={(value) => value}
              axisLabelMargin={10}
              yAxisUnit={['信用利差(bp)']}
              legendBottom={0}
            />
          ) : (
            <XYAxisChartsC
              isAbbreviate={true}
              axisLabelMargin={10}
              legendBottom={0}
              ref={(ref) => (refCharts1.current = ref)}
              axisLabelFormatter={(value) => value}
              yAxisUnit={['信用利差(bp)', '信用利差分位数(%)']}
              series={series1}
              xAxis={xAxis1}
              height={document.querySelector('#root').offsetHeight - 170}
              type='bar'
            />
          )}
        </div>
      </ModalC>
    </div>
  );
});
DimensionCustomization.propsTypes = {
  dataSource: PropTypes.array, // 源数据
  onClickRow: PropTypes.func, // 点击行
  onTabChange: PropTypes.func, // tab切换
};
export default connect(({ loading }) => ({ loading }), null, null, { forwardRef: true })(DimensionCustomization);
